package com.lixiangfeiyang.recycleritemhelperdemo

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.view.View
import android.view.animation.TranslateAnimation
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import java.util.*

/**
 * itemTouchHelper 工具类
 * 网格list 图片排序工具类
 * deleteView  底部隐藏的删除view
 */
class GridItemTouchHelperUtil( var adapter: ImageAdapter, var deleteView: View, var callBack: IsCanMoveCallBack) {

    private var draggingView: RecyclerView.ViewHolder? = null
    private var isDelete = false

    fun init(): ItemTouchHelper {
        val list = adapter.list
        var itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
            //  返回允许滑动的方向
            override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
                //竖直位移
                var dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
                //水平
                var swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
                //如果只要竖直方向位移 将水平位移只设置为0
                if (canMove(viewHolder)) {
                    return makeMovementFlags(dragFlags or swipeFlags, 0)
                } else {
                    return makeMovementFlags(0, 0)
                }
            }

            // 允许drag的前提下，当ItemTouchHelper想要将拖动的项目从其旧位置移动到新位置时调用
            override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
                // 获取被拖拽item和目标item的适配器索引（适配器索引是该item对应数据集的索引，getLayoutPosition是当前布局的位置）
                val from = viewHolder.adapterPosition
                val to = target.adapterPosition
                // 交换数据集的数据
                Collections.swap(list, from, to)
                // 通知Adapter更新
                adapter.notifyItemMoved(from, to)
                // 返回true表示item移到了目标位置
                return true
            }

            //是否允许侧滑删除 :允许swipe的前提下，当用户滑动ViewHolder触发临界时调用
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                // 获取滑动的item对应的适配器索引
                var pos = viewHolder.adapterPosition;
                // 从数据集移除数据
                list.remove(pos);
                // 通知Adapter更新
                adapter.notifyItemRemoved(pos);

            }

            //选中状态变化
            @SuppressLint("ResourceType")
            override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {

                when (actionState) {
                    //选中后回调 放大
                    ItemTouchHelper.ACTION_STATE_DRAG -> {
                        //显示动画
                        var showAnimation = TranslateAnimation(0f, 0f, 0f, -deleteView.height.toFloat())
                        showAnimation.duration = 600
                        showAnimation.fillAfter = true
                        deleteView.startAnimation(showAnimation)
                        draggingView = viewHolder
                        draggingView?.itemView?.apply {
                            scaleX = 1.1f
                            scaleY = 1.1f
                        }

                    }
                    //松手后回调 复原
                    ItemTouchHelper.ACTION_STATE_IDLE -> {
                        //隐藏删除区域
                        var hideAnimation = TranslateAnimation(0f, 0f, -deleteView.height.toFloat(), 0f)
                        hideAnimation.duration = 600
                        hideAnimation.fillAfter = true
                        deleteView.startAnimation(hideAnimation)
                        draggingView?.let {
                            //是否在删除区域松手
                            if (isDelete) {
                                //这里需要把拖拽的view gone掉 不然还会显示在UI上
                                draggingView!!.itemView.visibility = View.GONE
                                var currentList = adapter.list
                                currentList.removeAt(draggingView!!.adapterPosition)
                                adapter.notifyItemRemoved(draggingView!!.adapterPosition)
                            } else {
                                draggingView!!.itemView.apply {
                                    scaleX = 1f
                                    scaleY = 1f
                                }
                            }
                            draggingView = null
                        }

                    }

                }
            }

            override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
                val deleteViewLocations = IntArray(2)
                deleteView.getLocationInWindow(deleteViewLocations)
                //删除区域的顶部
                val deleteViewTop = deleteViewLocations[1]
                val dragViewLocations = IntArray(2)
                viewHolder.itemView.getLocationInWindow(dragViewLocations)
                //拖拽区域的底部 itemView的高度要*1.1是因为我们view被放大了所以我们高度也要一起变大
                val dragViewBottom = dragViewLocations[1] + viewHolder.itemView.height * 1.1f

                //判断拖拽区域的底部是否越过删除区域的顶部 保存是否在删除区域 当用户松手的时候我们可以用这个变量判断是否在删除区域松手
                if (dragViewBottom > deleteViewTop) {
                    isDelete = true
                    deleteView.alpha = .5f
                } else {
                    isDelete = false
                    deleteView.alpha = 1f
                }

            }

            //限制最后一个“+”不能移动
            override fun canDropOver(recyclerView: RecyclerView, current: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
                //这里判断逻辑简单起见 我就直接判断文案是否为“10”了 实际上可以判断viewholder的类型或其他方法
                return canMove(target)
            }


            //            但是会发现拖拽的item需要越过替换目标的时候才会触发onMove的回调，有没有办法让这个回调提前一点呢，比如移动到75%的时候就触发
            override fun chooseDropTarget(selected: RecyclerView.ViewHolder, dropTargets: MutableList<RecyclerView.ViewHolder>, curX: Int, curY: Int
            ): RecyclerView.ViewHolder? {
                val right = curX + selected.itemView.width
                val bottom = curY + selected.itemView.height
                var winner: RecyclerView.ViewHolder? = null
                var winnerScore = -1f
                val dx = curX - selected.itemView.left
                val dy = curY - selected.itemView.top

                //这里是0.75f 这个值不能小于getMoveThreshold()返回的阈值 如果想要小于的话，可以重写getMoveThreshold 返回一个最小值就好了
                val onMoveThreshold = 0.75f

                dropTargets.forEach { target ->

                    val ignoreWidth = target.itemView.width * (1 - onMoveThreshold)
                    val ignoreHeight = target.itemView.height * (1 - onMoveThreshold)

                    if (dx > 0) {
                        val diff = target.itemView.right - right - ignoreWidth
                        if (diff < 0 && target.itemView.right > selected.itemView.right) {
                            val score = Math.abs(diff)
                            if (score > winnerScore) {
                                winnerScore = score
                                winner = target
                            }
                        }
                    }
                    if (dx < 0) {
                        val diff = target.itemView.left - curX + ignoreWidth
                        if (diff > 0 && target.itemView.left < selected.itemView.left) {
                            val score = Math.abs(diff)
                            if (score > winnerScore) {
                                winnerScore = score
                                winner = target
                            }
                        }
                    }
                    if (dy < 0) {
                        val diff = target.itemView.top - curY + ignoreHeight
                        if (diff > 0 && target.itemView.top < selected.itemView.top) {
                            val score = Math.abs(diff)
                            if (score > winnerScore) {
                                winnerScore = score
                                winner = target
                            }
                        }
                    }
                    if (dy > 0) {
                        val diff = target.itemView.bottom - bottom - ignoreHeight
                        if (diff < 0 && target.itemView.bottom > selected.itemView.bottom) {
                            val score = Math.abs(diff)
                            if (score > winnerScore) {
                                winnerScore = score
                                winner = target
                            }
                        }
                    }
                }
                return winner
            }

            /**
             * 判断最后的图片中是否移动  false 不能移动 ture 能移动
             */
            private fun canMove(holder: RecyclerView.ViewHolder): Boolean {
                return isCanMove(adapter, holder)
            }

        })




        return itemTouchHelper;
    }


    fun isCanMove(adapter: ImageAdapter, holder: RecyclerView.ViewHolder): Boolean {
//        return adapter.list[holder.adapterPosition] != 10
        return callBack.itemCanMove(adapter, holder)
    }

    interface IsCanMoveCallBack {

        /**
         *  判断最后的图片中是否移动  false 不能移动 ture 能移动
         */
        fun itemCanMove(adapter: ImageAdapter, holder: RecyclerView.ViewHolder): Boolean
    }

}